package com.sghj.SysPermission.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sghj.SysPermission.entity.SysMenu;
import com.sghj.SysPermission.entity.SysUser;
import com.sghj.SysPermission.entity.SysUserrole;
import com.sghj.SysPermission.entity.Vo.updatePwdVO;
import com.sghj.SysPermission.entity.Vo.userAddVo;
import com.sghj.SysPermission.entity.Vo.userLoginVo;
import com.sghj.SysPermission.entity.Vo.userShowVo;
import com.sghj.SysPermission.service.SysMenuService;
import com.sghj.SysPermission.service.SysUserService;
import com.sghj.SysPermission.service.SysUserroleService;
import com.sghj.config.ReturnResult;
import com.sghj.config.handler.ResultCode;
import com.sghj.config.handler.exceptionHandler.MyException;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.mgt.eis.SessionDAO;
import org.apache.shiro.subject.SimplePrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.subject.support.DefaultSubjectContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Collection;
import java.util.List;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author xrx
 * @since 2022-02-18
 */
@RestController
@Slf4j
@RequestMapping("/sysUser")
public class SysUserController {
    @Autowired
    private SysUserService userService;
    @Autowired
    private SysMenuService menuService;
    @Autowired
    private SysUserroleService userroleService;
    @Autowired
    private SessionDAO sessionDAO;

    /**
     * 登录
     * @param userInfo
     * @return
     */
    @PostMapping("login")
    public ReturnResult login(@RequestBody userLoginVo userInfo){
        if (userInfo==null||userInfo.getUserName().equals("")||userInfo.getPassWord().equals("")){
            throw new MyException(ResultCode.PARAMETER,"缺少参数");
        }

        //获取当前用户
        Subject subject = SecurityUtils.getSubject();
        //生成shiro的token
        UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(userInfo.getUserName(), userInfo.getPassWord());
        //跳转到myRealm的登录方法中
        try {
            subject.login(usernamePasswordToken);
            //1.获取当前用户sessionid
            String currentUserSessionId = SecurityUtils.getSubject().getSession().getId().toString();
            //SysUser logiUser = (SysUser) subject.getPrincipal();

            //单账号登录验证
            Collection<Session> sessions = sessionDAO.getActiveSessions();
            if (sessions.size()>1){
                //System.out.println("仅允许单用户登录,开始清理遗留用户信息~");
                SysUser user= null;
                for (Session onlineSession : sessions){
                    SimplePrincipalCollection simplePrincipalCollection = (SimplePrincipalCollection) onlineSession.getAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY);
                    if (null == simplePrincipalCollection) {
                        sessionDAO.delete(onlineSession);
                        continue;
                    }
                    user = (SysUser) simplePrincipalCollection.getPrimaryPrincipal();
                    //4.清除当前用户以前登录时保存的session会话
                    if (!onlineSession.getId().equals(currentUserSessionId) && userInfo.getUserName().equals(user.getSysUserName())){
                        onlineSession.setTimeout(0);
                        sessionDAO.update(onlineSession);
                        //System.out.println("清理用户SessionId为["+onlineSession.getId()+"]的Session信息!");
                    }
                }
            }
            //存入session
            //subject.getSession().setAttribute("currentUser",subject.getPrincipal());
            //生成当前登录的token令牌
            String token =userService.createToken(userInfo);

            return ReturnResult.success().message("登录成功").data("token",token);
        }catch (UnknownAccountException uae){
            throw new MyException(20001,"用户不存在");
        }catch (IncorrectCredentialsException ice){
            throw new MyException(20001,"密码错误");
        }catch (AuthenticationException ae){
            throw new MyException(20001,"登录失败");
        }
    }

    /**
     * 根据请求获取当前用户信息
     * @param
     * @return
     */
    @GetMapping("getUserInfo")
    public ReturnResult getUserinfo(){
        //获取当前用户信息
        //SysUser user =userService.getUserInfoByToken(request);
        //SysUser userLogin = (SysUser) SecurityUtils.getSubject().getPrincipal();

        userShowVo user = userService.getUserInfoByToken();

        return ReturnResult.success().data("user", user);
    }

    /**
     * 获取当前用户路由信息
     * @return
     */
    @GetMapping("getRouter")
    public ReturnResult getRouter(){
        //获取用户路由信息
        List<SysMenu> menus = menuService.selectMenuTreeByUserId();

        return ReturnResult.success().data("menu",menus);
    }

    /**
     * 获取当前用户路由信息--------前台
     * @return
     */
    @GetMapping("getRouterFront/{memberid}")
    public ReturnResult getRouterFront(@PathVariable Integer memberid){
        //获取用户路由信息
        List<SysMenu> menus = menuService.selectMenuTreeByUserIdFront(memberid);

        return ReturnResult.success().data("menu",menus);
    }

    /**
     * 添加用户
     * @param user
     * @return
     */
    @RequiresPermissions("service:user:add")
    @PostMapping("addUser")
    public ReturnResult getUser(@Validated @RequestBody userAddVo user){
        if (user==null){
            throw new MyException(ResultCode.PARAMETER,"缺少参数");
        }
        int row =userService.addUser(user);
        if (row>0){
            return ReturnResult.success().message("添加成功");
        }
        return ReturnResult.failed().message("添加失败");
    }

    /**
     * 逻辑删除用户
     * @param uid
     * @return
     */
    @RequiresPermissions("service:user:remove")
    @PostMapping("removeUser/{uid}")
    public ReturnResult removeUser(@PathVariable Integer uid){
        SysUser user = userService.getById(uid);
        if (user==null){
            throw new MyException(ResultCode.NOTQUERIED,"该用户不存在");
        }
        //删除用户
        boolean b = userService.removeById(uid);
        //删除用户-角色关联信息
        userroleService.remove(new QueryWrapper<SysUserrole>().eq("SysUserId",uid));
        if (b){
            return ReturnResult.success().message("删除成功");
        }
        return ReturnResult.failed().message("删除失败");
    }

    /**
     * 修改用户信息
     * @return
     */
    @RequiresPermissions("service:user:update")
    @PostMapping("updateUser")
    public ReturnResult updateUser(@Validated @RequestBody userAddVo user){
        if (user==null||user.getSysUserId()==null||userService.getById(user.getSysUserId())==null){
            throw new MyException(ResultCode.NOTQUERIED,"该用户不存在");
        }
        int row = userService.updateUser(user);
        if (row>0){
            return ReturnResult.success().message("修改成功");
        }
        return ReturnResult.failed().message("修改失败");
    }

    /**
     * 根据id获取用户信息
     * @return
     */
    @GetMapping("getUserInfo/{userId}")
    public ReturnResult getUserInfo(@PathVariable Integer userId){

        if (userId==null||userService.getById(userId)==null){
            throw new MyException(ResultCode.NOTQUERIED,"该用户不存在");
        }

        userAddVo user =userService.getUserInfoById(userId);
        if (user!=null){
            return ReturnResult.success().data("user",user);
        }
        return ReturnResult.failed().message("没有查询到");
    }

    /**
     * 分页条件查询用户
     * @return
     */
    @RequiresPermissions("service:user:list")
    @PostMapping("getUserPage/{current}/{size}")
    public ReturnResult getUserPage(@PathVariable long current,@PathVariable long size,@RequestBody(required = false) SysUser user){
        if (current==0||size==0){
            throw new MyException(ResultCode.PARAMETER,"参数为空");
        }
        //创建分页
        IPage<userShowVo> page =new Page<>(current,size);
        IPage<userShowVo> userPage = userService.getUserPage(user, page);
        return ReturnResult.success().data("user",userPage.getRecords()).data("total",userPage.getTotal());
    }

    /**
     * 给用户分配角色
     * @param uid
     * @param roles
     * @return
     */
    @PostMapping("allocatRoles")
    public ReturnResult allocatRoles(Integer uid,int[] roles){
        if (uid==null||roles==null){
            throw new MyException(ResultCode.PARAMETER,"缺少参数");
        }
        if (userService.getById(uid)==null){
            throw new MyException(ResultCode.NOTQUERIED,"该用户不存在");
        }
        boolean b= userService.allocatRoles(uid,roles);
        if (b){
            return ReturnResult.success().message("分配角色成功");
        }
        return ReturnResult.failed().message("分配角色失败");
    }

    /**
     * 注册
     * @param user
     * @return
     */
    @PostMapping("register")
    public ReturnResult register(@Validated @RequestBody SysUser user){
        if (user==null){
            throw new MyException(ResultCode.PARAMETER,"缺少参数");
        }

        boolean save = userService.save(user);
        if (save){
            return ReturnResult.success().message("注册成功");
        }
        return ReturnResult.failed().message("注册失败");
    }

    /**
     * 重置密码
     * @param uid
     * @return
     */
    @RequiresPermissions("service:user:reset")
    @GetMapping("resetPassword/{uid}")
    public ReturnResult resetPassword(@PathVariable Integer uid){
        if (uid==null){
            throw new MyException(ResultCode.PARAMETER,"缺少参数");
        }

        int row = userService.resetPassword(uid);
        if (row>0){
            return ReturnResult.success().message("重置密码成功");
        }
        return ReturnResult.failed().message("重置密码失败");
    }

    /**
     * 登出
     * @return
     */
    @GetMapping("logout")
    public ReturnResult logout(){
        Subject subject = SecurityUtils.getSubject();
        subject.logout();
        return ReturnResult.success().message("登出成功");
    }

    /**
     * 修改当前用户密码
     * @param updatePwdVO
     * @return
     */
    @PostMapping("updatePassword")
    public ReturnResult updatePassword(@Validated @RequestBody updatePwdVO updatePwdVO){
        //判断旧密码
        String oldpwd=updatePwdVO.getOldPwd();


        int row =userService.updatePassword(updatePwdVO.getUid(),updatePwdVO.getPwd(),oldpwd);
        if (row>0){
            return ReturnResult.success().message("修改成功");
        }
        return ReturnResult.failed().message("修改失败");
    }

    @RequiresPermissions("service:cd:updateaa")
    //@RequiresRoles("admin·")
    //@Cacheable(cacheNames = "getuser",key="'getuser'")
    @PostMapping("ceshi")
    public Object ceshi(HttpServletRequest request) throws IOException {
        //
        //String encodeB = Base64Utils.encodeToString(FileUtil.readBytes("C:\\Users\\li\\Desktop\\b4d8cbfe326844cc1a4b76db194244f.jpg"));
        //System.out.println(encodeB);
        //return ReturnResult.success().data("photo",encodeA);

        //String s = "a";
        //SM4 sm4 = SmUtil.sm4("2c81b51b30feffbd".getBytes(StandardCharsets.UTF_8));
        //SecretKey secretKey = sm4.getSecretKey();
        //System.out.println("秘钥"+secretKey);
        //String abc = sm4.encryptHex(s, CharsetUtil.CHARSET_UTF_8);
        //return ReturnResult.success().data("a",secretKey);
        //List<InfoEmployee> list = employeeService.list(null);
        //for (InfoEmployee employee : list) {
        //    employee.setPhotoBase64("data:image/jpg;base64,"+employee.getPhotoBase64());
        //}
        //boolean b = employeeService.updateBatchById(list);
        //return ReturnResult.success().data("a",b);

        //String thumbnailBase64Photo = UploadImgUtils.getThumbnailBase64Photo(file);
        //return ReturnResult.success().data("a",thumbnailBase64Photo);
        //InfoEmployee byId = employeeService.getById(9999);
        //SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy");
        //String year = dateFormat.format(byId.getValidityDateEnd());
        //Integer integer = Integer.valueOf(year);
        //System.out.println(integer);
        //QueryWrapper<InfoEmployee> wrapper = new QueryWrapper<>();
        //SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-mm-dd");
        //Date parse = dateFormat.parse("2100-10-12");
        //wrapper.le("ValidityDateEnd",LocalDateTime.now());
        //List<InfoEmployee> list = employeeService.list(wrapper);

        //String s = UploadImgUtils.getThumbnailBase64Photo(photo);
        //
        //return ReturnResult.success().data("photo",s);
        //return userService.getById(1);
        //String s = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE2NjI1MzcxMTUsImlkIjoyNTcyLCJuaWNrbmFtZSI6IjIwNTYzMzAwMDM0NDAifQ.dQWl3sog2hcHbNbNcPSyAe7Sb7xXr5K44D4FsR4g0Os";
        //Long expire = redisTemplate.opsForValue().getOperations().getExpire("front_token:2572");
        //if (expire<14400){
        //    redisTemplate.opsForValue().set("front_token:2572", s, EXPIRE, TimeUnit.MILLISECONDS);
        //}
        //return ReturnResult.success();

        //UserAgent userAgent = UserAgent.parseUserAgentString(request.getHeader("User-Agent"));  //WINDOWS-CHROME
        ////获取浏览器信息
        //Browser browser = userAgent.getBrowser();
        ////获取浏览器版本
        //Version version = userAgent.getBrowserVersion();
        ////获取浏览器所有语言
        //String languages = request.getHeader("Accept-Language");
        ////获取操作系统
        //OperatingSystem os = userAgent.getOperatingSystem();    //WINDOWS
        ////获取ip地址
        //
        //String ip = "";
        //try {
        //    ip = InetAddress.getLocalHost().getHostAddress();   //192.168.50.34
        //} catch (UnknownHostException e) {
        //    e.printStackTrace();
        //
        //}
        //return ReturnResult.success().data("ip", ip).data("browser", browser).data("version", version).data("os", os);
       // Boolean bl = UploadImgUtils.GenerateImage(base64str, "D:\\picTmp\\"+  imgName +  ".jpg");
       //return ReturnResult.success().data("b",bl);
       // HttpSession session = request.getSession();
       // int maxInactiveInterval = session.getMaxInactiveInterval();
       // System.out.println(maxInactiveInterval);
       // return "{\"session时长\":\""+maxInactiveInterval+"\"}";
       // InfoEmployee byId = employeeService.getById(1223);
       // System.out.println(byId.MainInfotoString());
       // return null;
       // employeeService.clearPoints();
       // return null;

        //SysUser principal = (SysUser)SecurityUtils.getSubject().getPrincipal();
        //System.out.println("sessionid"+SecurityUtils.getSubject().getSession().getId());
        //
        //System.out.println(principal);
        log.info("这是一个日志");
        return null;
    }
}

